import { numberFormatter } from './index';

// 去除字符串中的空格
const Trim = str => (str ? str.replace(/\s/g, '') : '');

// [[key, value]] => [{ Key:Value }]
const parseArr = arr => {
  return arr.map(pItem => {
    return pItem.reduce((obj, cItem) => {
      obj[Trim(cItem.Key)] = cItem.Value;
      return obj;
    }, {});
  });
};

const polyType = {
  Sum: '求和',
  Avg: '平均值',
  Count: '计数',
  Max: '最大值',
  Min: '最小值',
};

const formatShowField = m => `${Trim(m.MeasureDisplayName)}(${polyType[m.FunName]})`;

const reporterTypeArr = [null, 'bar', 'pie', 'line', 'area', 'table', 'hbar'];

const placeholder = 'placeholder'; // 占位符

const dataParse = data => {
  const {
    // SortPredicate,
    // Measure,
    // ReprotName,
    Dimension = [],
    Reporter, // 报表类型编号
    ReporterConfig = {},
    SummaryType, // 是否 汇总 '1'/'0'
    MacroType, // 是否 极简模式 '1'/'0'
  } = data;

  // const reporterType = 'table';
  const reporterType = reporterTypeArr[Reporter] || 'table';

  let DataJson = data.DataJson || [];

  let summary = [];
  // 如果是极简模式
  if (Number(SummaryType) === 1) {
    summary = DataJson[DataJson.length - 1];
    DataJson = DataJson.slice(0, DataJson.length - 1);
  }

  // 维度 ["营业信息_主管", "营业信息_年度"]
  let dimensionList = [];
  // 度量list ['营业信息_微信合计', '营业信息_现金合计']
  let measureList = [];
  // 判断是否行转列
  const ReporterExtendConfig = ReporterConfig.ReporterExtendConfig || {};
  const ReporterBaseConfig = ReporterConfig.ReporterBaseConfig || [];
  const { ConvertType, NewDimension, NewMeasure } = ReporterExtendConfig;
  if (ConvertType && NewDimension && NewMeasure) {
    dimensionList = NewDimension.split(',').map(e => ({ key: e, label: e }));
    measureList = NewMeasure.split(',').map(e => ({ key: e, label: e }));
  } else {
    dimensionList = Dimension.split(',').map(e => ({ key: e, label: e }));
    measureList = ReporterBaseConfig.map(m => ({
      key: m.ReprotName,
      label: formatShowField(m),
    }));
    // measureList = ReporterBaseConfig.map(m => `${Trim(m.MeasureField)}${polyType[m.FunName]}`);
  }

  const [firstDimension = {}, secendDimension = {}] = dimensionList;

  // 将数据转换成可用的数据
  let legendData = new Set();
  const dimensionAxis = new Set();
  const dataList = parseArr(DataJson);
  // 当类型为table时 就不需要转换了,直接使用datajson,
  const datas =
    reporterType === 'table'
      ? DataJson
      : dataList.reduce((obj, dataItem) => {
          for (const measureItem of measureList) {
            const { key } = measureItem;
            const value = dataItem[key];
            // 通常情况下
            let firstDimensionValue = dataItem[firstDimension.key];
            let secendDimensionValue = dataItem[secendDimension.key];
            // 行列转置时
            if (ConvertType) {
              const firstDimensionRbc = ReporterBaseConfig.find(
                rbc => rbc.ReprotName === firstDimensionValue
              );
              const secendDimensionRbc = ReporterBaseConfig.find(
                rbc => rbc.ReprotName === secendDimensionValue
              );
              if (firstDimensionRbc) {
                firstDimensionValue =
                  firstDimensionRbc.MeasureDisplayName || firstDimensionRbc.MeasureField;
                // firstDimensionValue = formatShowField(firstDimensionRbc)
              } else if (secendDimensionRbc) {
                secendDimensionValue =
                  secendDimensionRbc.MeasureDisplayName || secendDimensionRbc.MeasureField;
              }
            }
            if (secendDimensionValue) {
              // 如果有副维度就加图例
              legendData.add(secendDimensionValue);
            } else {
              // 如果没有副维度就给个占位符
              secendDimensionValue = placeholder;
            }
            // 维度轴
            dimensionAxis.add(firstDimensionValue);
            // 新建对应的值或者加入对应的值
            obj[key] = obj[key] || {};
            obj[key][secendDimensionValue] = obj[key][secendDimensionValue] || [];

            obj[key][secendDimensionValue].push({
              value,
              name: firstDimensionValue,
            });
          }
          return obj;
        }, {});

  // 行列转置 图例使用  ReporterBaseConfig
  // if (ConvertType) {
  //   legendData = ReporterBaseConfig.map(e => e.MeasureDisplayName || e.ReprotName);
  // }

  return {
    ...data,
    datas,
    legendData: [...legendData],
    dimensionAxis: [...dimensionAxis],
    dimensionList,
    measureList,
    reporterType,
    ConvertType,
    MacroType,
    summary,
    SummaryType,
  };
};
/**
 *
 * @param {*} param0 { 图例，主轴，数据， 类型  }
 */
const setOption = ({ parseData, currentMeasure, isPreview = false }) => {
  const {
    legendData,
    dimensionAxis,
    datas,
    measureList,
    dimensionList,
    reporterType,
    MacroType,
    summary,
    SummaryType,
  } = parseData;

  // 如果是表格直接返回表格需要的数据
  if (reporterType === 'table') {
    return {
      measureList,
      sourceData: datas,
      dimensionList,
    };
  }

  // 没有选择度量就用第一个
  const currentMeasureInfo = measureList.find(e => e.key === currentMeasure) || measureList[0] || {}
  // console.log(currentMeasureInfo)
  const seriesArr = Object.values(datas[currentMeasureInfo.key] || {}).map(ser => {
    // 部分数据没有提供，这里设置值为0来填充
    return dimensionAxis.map(name => {
      const item = ser.find(s => s.name === name);
      if (item) {
        return item;
      }
      return {
        name,
        value: 0,
      };
    });
  });

  // 预览时 pei 饼图比较特殊， 只显示主维度的一条数据
  if (isPreview && reporterType === 'pie') {
    seriesArr.length = 1;
  }

  // 是否极简模式：极简模式不显示刻度数和条目
  const isMacroType = Number(MacroType) === 1;

  // 是否汇总
  const isSummary = Number(SummaryType);
  let summaryObj = {};
  if (isSummary && summary) {
    for (const measure of measureList) {
      const summaryItem = summary.find(s => s.Key === measure.key);
      if (summaryItem) {
        summaryObj.name = measure.label;
        summaryObj.value = summaryItem.Value;
        break;
      }
    }
  }

  // 图例
  const legend = legendArr => ({
    data: legendArr,
    type: 'scroll',
    selected: legendArr.reduce((obj, item, index) => ({ ...obj, [item]: index < 10 }), {}),
  });

  // 数据轴
  const numberAxis = {
    axisLabel: {
      formatter: numberFormatter,
    },
    show: !isMacroType,
  };

  // 项目轴
  const itemAxis = {
    data: dimensionAxis,
    show: !isMacroType,
    axisLabel: {
      rotate: -30,
    },
  };

  const option = {
    grid: {
      containLabel: true,
      bottom: '10%',
    },
    title: isSummary
      ? {
          text: `\n\n${summaryObj.name}:${summaryObj.value}\n`,
          top: 2,
          left: 'center',
          textStyle: {
            fontSize: 15,
            // fontStyle:'italic',
            fontWeight: 600,
            color: '#333333',
          },
        }
      : null,
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
      },
      confine: true,
    },
    legend: legend(legendData),
    xAxis: itemAxis,
    yAxis: numberAxis,
  };

  switch (reporterType) {
    case 'hbar':
      return {
        ...option,
        xAxis: numberAxis,
        yAxis: itemAxis,
        series: seriesArr.map((series = [], index) => ({
          type: 'bar',
          name: legendData[index],
          data: series,
        })),
      };
    case 'line':
      return {
        ...option,
        yAxis: {
          ...numberAxis,
          splitLine: {
            show: true,
          },
        },
        series: seriesArr.map((series = [], index) => ({
          type: 'line',
          name: legendData[index],
          data: series,
        })),
      };
    case 'area':
      return {
        ...option,
        series: seriesArr.map((series = [], index) => ({
          // stack: '总量',
          areaStyle: { opacity: 0.3 },
          type: 'line',
          name: legendData[index],
          data: series,
        })),
      };
    case 'pie':
      return {
        ...option,
        xAxis: null,
        yAxis: null,
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b} : {c} ({d}%)',
          confine: true,
        },
        legend: legend(dimensionAxis),
        series: seriesArr.map((series = [], index) => {
          const marginTop = `${((index * 2 + 1.2) / (seriesArr.length * 2)) * 100}%`;
          return {
            radius: '40%',
            center: ['50%', marginTop],
            type: reporterType,
            name: legendData[index] || currentMeasureInfo.label,
            data: series,
          };
        }),
      };
    case 'bar':
    default:
      return {
        ...option,
        series: seriesArr.map((series = [], index) => ({
          type: 'bar',
          name: legendData[index],
          data: series,
        })),
      };
  }
};

export default { dataParse, Trim, parseArr, setOption, numberFormatter };
